home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / dflat8.zip / POPDOWN.C < prev    next >
Text File  |  1991-09-30  |  8KB  |  344 lines

  1. /* ------------- popdown.c ----------- */
  2.  
  3. #include "dflat.h"
  4.  
  5. static int SelectionWidth(struct PopDown *);
  6. static int py = -1;
  7.  
  8. static int CreateWindowMsg(WINDOW wnd)
  9. {
  10.     int rtn;
  11.     ClearAttribute(wnd, HASTITLEBAR     |
  12.                         VSCROLLBAR     |
  13.                         MOVEABLE     |
  14.                         SIZEABLE     |
  15.                         HSCROLLBAR);
  16.     rtn = BaseWndProc(POPDOWNMENU, wnd, CREATE_WINDOW, 0, 0);
  17.     SendMessage(wnd, CAPTURE_MOUSE, 0, 0);
  18.     SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0);
  19.     SendMessage(NULL, SAVE_CURSOR, 0, 0);
  20.     SendMessage(NULL, HIDE_CURSOR, 0, 0);
  21.     return rtn;
  22. }
  23.  
  24. static void LeftButtonMsg(WINDOW wnd, PARAM p1, PARAM p2)
  25. {
  26.     int my = (int) p2 - GetTop(wnd);
  27.     if (InsideRect(p1, p2, ClientRect(wnd)))    {
  28.         if (my != py)    {
  29.             SendMessage(wnd, LB_SELECTION,
  30.                     (PARAM) wnd->wtop+my-1, TRUE);
  31.             py = my;
  32.         }
  33.     }
  34.     else if ((int)p2 == GetTop(GetParent(wnd)))
  35.         if (GetClass(GetParent(wnd)) == MENUBAR)
  36.             PostMessage(GetParent(wnd), LEFT_BUTTON, p1, p2);
  37. }
  38.  
  39. static int ButtonReleasedMsg(WINDOW wnd, PARAM p1, PARAM p2)
  40. {
  41.     py = -1;
  42.     if (InsideRect((int)p1, (int)p2, ClientRect(wnd)))    {
  43.         int sel = (int)p2 - GetClientTop(wnd);
  44.         if (*TextLine(wnd, sel) != LINE)
  45.             SendMessage(wnd, LB_CHOOSE, wnd->selection, 0);
  46.     }
  47.     else    {
  48.         WINDOW pwnd = GetParent(wnd);
  49.         if (GetClass(pwnd) == MENUBAR && (int)p2 == GetTop(pwnd))
  50.             return FALSE;
  51.         if ((int)p1 == GetLeft(pwnd)+2)
  52.             return FALSE;
  53.         SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  54.         return TRUE;
  55.     }
  56.     return FALSE;
  57. }
  58.  
  59. static void PaintMsg(WINDOW wnd)
  60. {
  61.     int wd;
  62.     unsigned char sep[80], *cp = sep;
  63.     unsigned char sel[80];
  64.     struct PopDown *ActivePopDown;
  65.     struct PopDown *pd1;
  66.  
  67.     ActivePopDown = pd1 = wnd->mnu->Selections;
  68.     wd = MenuWidth(ActivePopDown)-2;
  69.     while (wd--)
  70.         *cp++ = LINE;
  71.     *cp = '\0';
  72.     SendMessage(wnd, CLEARTEXT, 0, 0);
  73.     wnd->selection = wnd->mnu->Selection;
  74.     while (pd1->SelectionTitle != NULL)    {
  75.         if (*pd1->SelectionTitle == LINE)
  76.             SendMessage(wnd, ADDTEXT, (PARAM) sep, 0);
  77.         else    {
  78.             int len;
  79.             memset(sel, '\0', sizeof sel);
  80.             if (pd1->Attrib & INACTIVE)
  81.                 sprintf(sel, "%c%c%c",
  82.                     CHANGECOLOR,
  83.                     wnd->WindowColors [HILITE_COLOR] [FG] | 0x80,
  84.                     wnd->WindowColors [STD_COLOR] [BG] | 0x80);
  85.             strcat(sel, " ");
  86.             if (pd1->Attrib & CHECKED)
  87.                 sel[strlen(sel)-1] = CHECKMARK;
  88.             len = CopyCommand(sel+strlen(sel), pd1->SelectionTitle,
  89.                     pd1->Attrib & INACTIVE, wnd->WindowColors [STD_COLOR] [BG]);
  90.             if (pd1->Accelerator)    {
  91.                 int i;
  92.                 int wd1 = 2+SelectionWidth(ActivePopDown) - strlen(pd1->SelectionTitle);
  93.                 for (i = 0; keys[i].keylabel; i++)    {
  94.                     if (keys[i].keycode == pd1->Accelerator)    {
  95.                         while (wd1--)
  96.                             strcat(sel, " ");
  97.                         sprintf(sel+strlen(sel), "[%s]", keys[i].keylabel);
  98.                         break;
  99.                     }
  100.                 }
  101.             }
  102.             if (pd1->Attrib & CASCADED)    {
  103.                 if (!pd1->Accelerator)    {
  104.                     wd = MenuWidth(ActivePopDown)-len+1;
  105.                     while (wd--)
  106.                         strcat(sel, " ");
  107.                 }
  108.                 sel[strlen(sel)-1] = CASCADEPOINTER;
  109.             }
  110.             else
  111.                 strcat(sel, " ");
  112.             strcat(sel, " ");
  113.             sel[strlen(sel)-1] = RESETCOLOR;
  114.             SendMessage(wnd, ADDTEXT, (PARAM) sel, 0);
  115.         }
  116.         pd1++;
  117.     }
  118. }
  119.  
  120. static int BorderMsg(WINDOW wnd)
  121. {
  122.     int i, rtn = TRUE;
  123.     WINDOW currFocus;
  124.     if (wnd->mnu != NULL)    {
  125.         currFocus = inFocus;
  126.         inFocus = NULL;
  127.         rtn = BaseWndProc(POPDOWNMENU, wnd, BORDER, 0, 0);
  128.         inFocus = currFocus;
  129.         for (i = 0; i < ClientHeight(wnd); i++)    {
  130.             if (*TextLine(wnd, i) == LINE)    {
  131.                 wputch(wnd, LEDGE, 0, i+1);
  132.                 wputch(wnd, REDGE, WindowWidth(wnd)-1, i+1);
  133.             }
  134.         }
  135.     }
  136.     return rtn;
  137. }
  138.  
  139. static void LBChooseMsg(WINDOW wnd, PARAM p1)
  140. {
  141.     struct PopDown *ActivePopDown = wnd->mnu->Selections;
  142.     if (ActivePopDown != NULL)    {
  143.         int *attr = &(ActivePopDown+(int)p1)->Attrib;
  144.         wnd->mnu->Selection = (int)p1;
  145.         if (!(*attr & INACTIVE))    {
  146.             if (*attr & TOGGLE)
  147.                 *attr ^= CHECKED;
  148.             PostMessage(GetParent(wnd), COMMAND,
  149.                 (ActivePopDown+(int)p1)->ActionId, p1);
  150.         }
  151.         else
  152.             beep();
  153.     }
  154. }
  155.  
  156. static int KeyboardMsg(WINDOW wnd, PARAM p1, PARAM p2)
  157. {
  158.     struct PopDown *ActivePopDown = wnd->mnu->Selections;
  159.     if (wnd->mnu != NULL)    {
  160.         if (ActivePopDown != NULL)    {
  161.             int c = (int)p1;
  162.             int sel = 0;
  163.             int a;
  164.             struct PopDown *pd = ActivePopDown;
  165.  
  166.             if ((c & OFFSET) == 0)
  167.                 c = tolower(c);
  168.             a = AltConvert(c);
  169.  
  170.             while (pd->SelectionTitle != NULL)    {
  171.                 char *cp = strchr(pd->SelectionTitle,
  172.                                 SHORTCUTCHAR);
  173.                 int sc = tolower(*(cp+1));
  174.                 if ((cp && sc == c) ||
  175.                         (a && sc == a) ||
  176.                             pd->Accelerator == c)    {
  177.                     PostMessage(wnd, LB_SELECTION, sel, 0);
  178.                     PostMessage(wnd, LB_CHOOSE, sel, TRUE);
  179.                     return TRUE;
  180.                 }
  181.                 pd++, sel++;
  182.             }
  183.         }
  184.     }
  185.     switch ((int)p1)    {
  186.         case F1:
  187.             if (ActivePopDown == NULL)
  188.                 SendMessage(GetParent(wnd), KEYBOARD, p1, p2);
  189.             else 
  190.                 DisplayHelp(wnd, (ActivePopDown+wnd->selection)->help);
  191.             return TRUE;
  192.         case ESC:
  193.             SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  194.             return TRUE;
  195.         case FWD:
  196.         case BS:
  197.             if (GetClass(GetParent(wnd)) == MENUBAR)
  198.                 PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
  199.             return TRUE;
  200.         case UP:
  201.             if (wnd->selection == 0)    {
  202.                 if (wnd->wlines == ClientHeight(wnd))    {
  203.                     PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
  204.                     return TRUE;
  205.                 }
  206.             }
  207.             break;
  208.         case DN:
  209.             if (wnd->selection == wnd->wlines-1)    {
  210.                 if (wnd->wlines == ClientHeight(wnd))    {
  211.                     PostMessage(wnd, LB_SELECTION, 0, FALSE);
  212.                     return TRUE;
  213.                 }
  214.             }
  215.             break;
  216.         case HOME:
  217.         case END:
  218.         case '\r':
  219.             break;
  220.         default:
  221.             return TRUE;
  222.     }
  223.     return FALSE;
  224. }
  225.  
  226. static int CloseWindowMsg(WINDOW wnd, PARAM p1, PARAM p2)
  227. {
  228.     int rtn;
  229.     WINDOW pwnd = GetParent(wnd);
  230.     SendMessage(wnd, RELEASE_MOUSE, 0, 0);
  231.     SendMessage(wnd, RELEASE_KEYBOARD, 0, 0);
  232.     SendMessage(NULL, RESTORE_CURSOR, 0, 0);
  233.     rtn = BaseWndProc(POPDOWNMENU, wnd, CLOSE_WINDOW, p1, p2);
  234.     SendMessage(pwnd, CLOSE_POPDOWN, p1, 0);
  235.     return rtn;
  236. }
  237.  
  238. int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  239. {
  240.     switch (msg)    {
  241.         case CREATE_WINDOW:
  242.             return CreateWindowMsg(wnd);
  243.         case LEFT_BUTTON:
  244.             LeftButtonMsg(wnd, p1, p2);
  245.             return FALSE;
  246.         case DOUBLE_CLICK:
  247.             return TRUE;
  248.         case LB_SELECTION:
  249.             if (*TextLine(wnd, (int)p1) == LINE)
  250.                 return TRUE;
  251.             wnd->mnu->Selection = (int)p1;
  252.             break;
  253.         case BUTTON_RELEASED:
  254.             if (ButtonReleasedMsg(wnd, p1, p2))
  255.                 return TRUE;
  256.             break;
  257.         case BUILD_SELECTIONS:
  258.             wnd->mnu = (void *) p1;
  259.             wnd->selection = wnd->mnu->Selection;
  260.             break;
  261.         case PAINT:
  262.             if (wnd->mnu == NULL)
  263.                 return TRUE;
  264.             PaintMsg(wnd);
  265.             break;
  266.         case BORDER:
  267.             return BorderMsg(wnd);
  268.         case LB_CHOOSE:
  269.             LBChooseMsg(wnd, p1);
  270.             return TRUE;
  271.         case KEYBOARD:
  272.             if (KeyboardMsg(wnd, p1, p2))
  273.                 return TRUE;
  274.             break;
  275.         case CLOSE_WINDOW:
  276.             return CloseWindowMsg(wnd, p1, p2);
  277.         default:
  278.             break;
  279.     }
  280.     return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
  281. }
  282.  
  283. int MenuHeight(struct PopDown *pd)
  284. {
  285.     int ht = 0;
  286.     while (pd[ht].SelectionTitle != NULL)
  287.         ht++;
  288.     return ht+2;
  289. }
  290.  
  291. int MenuWidth(struct PopDown *pd)
  292. {
  293.     int wd = 0, i;
  294.     int len = 0;
  295.  
  296.     wd = SelectionWidth(pd);
  297.     while (pd->SelectionTitle != NULL)    {
  298.         if (pd->Accelerator)    {
  299.             for (i = 0; keys[i].keylabel; i++)
  300.                 if (keys[i].keycode == pd->Accelerator)    {
  301.                     len = max(len, 2+strlen(keys[i].keylabel));
  302.                     break;
  303.                 }
  304.         }
  305.         if (pd->Attrib & CASCADED)
  306.             len = max(len, 2);
  307.         pd++;
  308.     }
  309.     return wd+5+len;
  310. }
  311.  
  312. static int SelectionWidth(struct PopDown *pd)
  313. {
  314.     int wd = 0;
  315.     while (pd->SelectionTitle != NULL)    {
  316.         int len = strlen(pd->SelectionTitle)-1;
  317.         wd = max(wd, len);
  318.         pd++;
  319.     }
  320.     return wd;
  321. }
  322.  
  323. int CopyCommand(unsigned char *dest, unsigned char *src,
  324.                                         int skipcolor, int bg)
  325. {
  326.     unsigned char *d = dest;
  327.     while (*src && *src != '\n')    {
  328.         if (*src == SHORTCUTCHAR)    {
  329.             src++;
  330.             if (!skipcolor)    {
  331.                 *dest++ = CHANGECOLOR;
  332.                 *dest++ = cfg.clr[POPDOWNMENU] [HILITE_COLOR] [BG] | 0x80;
  333.                 *dest++ = bg | 0x80;
  334.                 *dest++ = *src++;
  335.                 *dest++ = RESETCOLOR;
  336.             }
  337.         }
  338.         else
  339.             *dest++ = *src++;
  340.     }
  341.     return (int) (dest - d);
  342. }
  343.  
  344.